#include "systemmonitor.h"
#include "utils.h"
#include <fstream>
#include <sstream>
#include <unistd.h>
#include <sys/utsname.h>

SystemMonitor::SystemMonitor() 
    : m_last_cpu_total(0), 
      m_last_cpu_idle(0),
      m_last_network_rx_bytes(0),
      m_last_network_tx_bytes(0),
      m_last_disk_read_bytes(0),
      m_last_disk_write_bytes(0) {
    // 构造函数
}

SystemMonitor::~SystemMonitor() {
    // 析构函数
}

SystemInfo SystemMonitor::get_system_info() {
    SystemInfo info = {};
    
    // 获取CPU使用率
    std::ifstream cpu_file("/proc/stat");
    if (cpu_file.is_open()) {
        std::string line;
        std::getline(cpu_file, line);
        
        if (line.substr(0, 3) == "cpu") {
            std::istringstream iss(line);
            std::string cpu_label;
            unsigned long user, nice, system, idle, iowait, irq, softirq, steal;
            
            iss >> cpu_label >> user >> nice >> system >> idle >> iowait >> irq >> softirq >> steal;
            
            unsigned long long total = user + nice + system + idle + iowait + irq + softirq + steal;
            unsigned long long total_idle = idle + iowait;
            
            if (m_last_cpu_total != 0) {
                unsigned long long total_diff = total - m_last_cpu_total;
                unsigned long long idle_diff = total_idle - m_last_cpu_idle;
                
                if (total_diff > 0) {
                    info.cpu_percent = 100.0 * (total_diff - idle_diff) / total_diff;
                }
            }
            
            m_last_cpu_total = total;
            m_last_cpu_idle = total_idle;
        }
    }
    
    // 获取内存信息
    std::ifstream mem_file("/proc/meminfo");
    if (mem_file.is_open()) {
        std::string line;
        long mem_total = 0, mem_free = 0, mem_buffers = 0, mem_cached = 0;
        
        while (std::getline(mem_file, line)) {
            std::istringstream iss(line);
            std::string key;
            long value;
            
            iss >> key >> value;
            
            if (key == "MemTotal:") {
                mem_total = value;
            } else if (key == "MemFree:") {
                mem_free = value;
            } else if (key == "Buffers:") {
                mem_buffers = value;
            } else if (key == "Cached:") {
                mem_cached = value;
            }
        }
        
        if (mem_total > 0) {
            long mem_used = mem_total - mem_free - mem_buffers - mem_cached;
            info.memory_percent = 100.0 * mem_used / mem_total;
            info.memory_total_mb = mem_total / 1024.0;
            info.memory_used_mb = mem_used / 1024.0;
        }
    }
    
    // 获取系统信息
    struct utsname sys_info;
    if (uname(&sys_info) == 0) {
        info.hostname = sys_info.nodename;
        
        // 从/proc/version获取内核版本
        std::string kernel_version = sys_info.release;
        
        // 从/etc/os-release获取发行版信息
        std::string distro_name = "Linux";
        std::string distro_version = "";
        std::string pretty_name = "";
        
        std::ifstream os_release_file("/etc/os-release");
        if (os_release_file.is_open()) {
            std::string line;
            while (std::getline(os_release_file, line)) {
                if (line.substr(0, 11) == "PRETTY_NAME=") {
                    // 提取完整的发行版名称
                    pretty_name = line.substr(12); // 跳过 "PRETTY_NAME="
                    // 移除引号
                    if (pretty_name.length() > 0 && pretty_name[0] == '"') {
                        pretty_name = pretty_name.substr(1, pretty_name.length() - 2);
                    }
                } else if (line.substr(0, 5) == "NAME=" && pretty_name.empty()) {
                    // 备选方案：使用NAME字段
                    distro_name = line.substr(5); // 跳过 "NAME="
                    // 移除引号
                    if (distro_name.length() > 0 && distro_name[0] == '"') {
                        distro_name = distro_name.substr(1, distro_name.length() - 2);
                    }
                } else if (line.substr(0, 8) == "VERSION=" && pretty_name.empty()) {
                    // 提取版本信息
                    distro_version = line.substr(8); // 跳过 "VERSION="
                    // 移除引号
                    if (distro_version.length() > 0 && distro_version[0] == '"') {
                        distro_version = distro_version.substr(1, distro_version.length() - 2);
                    }
                }
            }
        }
        
        // 构造完整的操作系统信息
        if (!pretty_name.empty()) {
            info.os_name = pretty_name + " (Linux " + kernel_version + ")";
        } else if (!distro_version.empty()) {
            info.os_name = distro_name + " " + distro_version + " (Linux " + kernel_version + ")";
        } else {
            info.os_name = distro_name + " (Linux " + kernel_version + ")";
        }
        
        info.kernel_version = kernel_version;
    }
    
    // 获取运行时间
    std::ifstream uptime_file("/proc/uptime");
    if (uptime_file.is_open()) {
        double uptime_seconds;
        uptime_file >> uptime_seconds;
        
        int total_seconds = (int)uptime_seconds;
        info.uptime_hours = total_seconds / 3600;
        info.uptime_minutes = (total_seconds % 3600) / 60;
        info.uptime_seconds = total_seconds % 60;
    }
    
    // 获取负载均衡信息
    std::ifstream loadavg_file("/proc/loadavg");
    if (loadavg_file.is_open()) {
        loadavg_file >> info.load_average_1min >> info.load_average_5min >> info.load_average_15min;
    }
    
    // 获取进程信息
    std::ifstream stat_file("/proc/stat");
    if (stat_file.is_open()) {
        std::string line;
        while (std::getline(stat_file, line)) {
            if (line.substr(0, 6) == "procs_") {
                std::istringstream iss(line);
                std::string key;
                int value;
                iss >> key >> value;
                
                if (key == "procs_running") {
                    info.processes_running = value;
                } else if (key == "procs_blocked") {
                    // 这里简单处理，实际应该区分睡眠状态
                    info.processes_sleeping = value;
                }
            }
        }
        // 简化处理，实际应该统计所有进程
        info.processes_total = info.processes_running + info.processes_sleeping;
    }
    
    // 获取CPU型号和核心数
    std::ifstream cpuinfo_file("/proc/cpuinfo");
    if (cpuinfo_file.is_open()) {
        std::string line;
        int core_count = 0;
        while (std::getline(cpuinfo_file, line)) {
            if (line.substr(0, 10) == "model name") {
                if (info.cpu_model.empty()) {
                    size_t pos = line.find(": ");
                    if (pos != std::string::npos) {
                        info.cpu_model = line.substr(pos + 2);
                    }
                }
            } else if (line.substr(0, 9) == "processor") {
                core_count++;
            }
        }
        info.cpu_cores = core_count > 0 ? core_count : 1;
    }
    
    // 获取网络信息
    std::ifstream net_file("/proc/net/dev");
    if (net_file.is_open()) {
        std::string line;
        // 跳过前两行标题
        std::getline(net_file, line);
        std::getline(net_file, line);
        
        long long total_rx = 0, total_tx = 0;
        while (std::getline(net_file, line)) {
            // 解析网络接口数据
            std::istringstream iss(line);
            std::string interface;
            long long rx_bytes, tx_bytes;
            
            iss >> interface >> rx_bytes;
            
            // 跳过其他字段直到tx_bytes
            for (int i = 0; i < 7; i++) {
                long long dummy;
                iss >> dummy;
            }
            iss >> tx_bytes;
            
            total_rx += rx_bytes;
            total_tx += tx_bytes;
        }
        
        // 计算网络速度（字节/秒）
        if (m_last_network_rx_bytes != 0 && m_last_network_tx_bytes != 0) {
            // 注意：这里假设更新频率是固定的，实际应该使用真实的时间间隔
            // 简化处理，假设每秒更新一次
            info.network_rx_bytes = total_rx - m_last_network_rx_bytes;
            info.network_tx_bytes = total_tx - m_last_network_tx_bytes;
        } else {
            // 第一次运行时没有历史数据
            info.network_rx_bytes = 0;
            info.network_tx_bytes = 0;
        }
        
        m_last_network_rx_bytes = total_rx;
        m_last_network_tx_bytes = total_tx;
    }
    
    // 获取磁盘信息
    std::ifstream diskstats_file("/proc/diskstats");
    if (diskstats_file.is_open()) {
        std::string line;
        long long total_reads = 0, total_writes = 0;
        
        // 读取所有磁盘的统计信息
        while (std::getline(diskstats_file, line)) {
            std::istringstream iss(line);
            std::string device_name;
            int major, minor;
            long long reads, reads_merged, sectors_read, time_reading;
            long long writes, writes_merged, sectors_written, time_writing;
            long long in_flight, time_in_queue;
            
            iss >> major >> minor >> device_name 
               >> reads >> reads_merged >> sectors_read >> time_reading
               >> writes >> writes_merged >> sectors_written >> time_writing
               >> in_flight >> time_in_queue;
            
            // 只统计物理磁盘设备（通常以sd, hd, nvme开头）
            if (device_name.length() >= 3 && 
                (device_name.substr(0, 2) == "sd" || 
                 device_name.substr(0, 2) == "hd" ||
                 device_name.substr(0, 4) == "nvme")) {
                total_reads += sectors_read;   // 扇区大小通常是512字节
                total_writes += sectors_written;
            }
        }
        
        // 计算读写速度（MB/s）
        if (m_last_disk_read_bytes != 0 && m_last_disk_write_bytes != 0) {
            long long read_diff = total_reads * 512 - m_last_disk_read_bytes;   // 转换为字节
            long long write_diff = total_writes * 512 - m_last_disk_write_bytes; // 转换为字节
            
            // 简化处理，实际应该考虑时间间隔
            info.disk_read_speed_mbs = read_diff / (1024.0 * 1024.0);  // 转换为MB
            info.disk_write_speed_mbs = write_diff / (1024.0 * 1024.0); // 转换为MB
        }
        
        m_last_disk_read_bytes = total_reads * 512;
        m_last_disk_write_bytes = total_writes * 512;
    }
    
    // 设置默认磁盘信息
    info.disk_percent = 0.0;
    info.disk_total_gb = 100.0;
    info.disk_used_gb = 20.0;
    
    return info;
}